<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>第 1 天</title>
    <style>
        #graph-container{
            position: absolute;
            top: 0;
            right: 0;
            bottom: 0;
            left: 0;
        }
    </style>
</head>
<body>
    <div id="graph-container"></div>
</body>

<script src="../js/g6.min.js"></script>
<script>
    // 准备容器
    const container = document.getElementById('graph-container');
    const width = container.scrollWidth;
    const height = container.scrollHeight;

    // 准备数据
    const data = {
        "id": "Modeling Methods",
        "children": [
            {
                "id": "Classification",
                "children": [
                    { "id": "Logistic regression" },
                    { "id": "Linear discriminant analysis" },
                    { "id": "Rules" },
                    { "id": "Decision trees" },
                    { "id": "Naive Bayes" },
                    { "id": "K nearest neighbor" },
                    { "id": "Probabilistic neural network" },
                    { "id": "Support vector machine" }
                ]
            },
            {
                "id": "Consensus",
                "children": [
                    {
                        "id": "Models diversity",
                        "children": [
                            { "id": "Different initializations" },
                            { "id": "Different parameter choices" },
                            { "id": "Different architectures" },
                            { "id": "Different modeling methods" },
                            { "id": "Different training sets" },
                            { "id": "Different feature sets" }
                        ]
                    },
                    {
                        "id": "Methods",
                        "children": [
                            { "id": "Classifier selection" },
                            { "id": "Classifier fusion" }
                        ]
                    },
                    {
                        "id": "Common",
                        "children": [
                            { "id": "Bagging" },
                            { "id": "Boosting" },
                            { "id": "AdaBoost" }
                        ]
                    }
                ]
            },
            {
                "id": "Regression",
                "children": [
                    { "id": "Multiple linear regression" },
                    { "id": "Partial least squares" },
                    { "id": "Multi-layer feedforward neural network" },
                    { "id": "General regression neural network" },
                    { "id": "Support vector regression" }
                ]
            }
        ]
    }

    // 实例化 G6
    const graph = new G6.TreeGraph({
        container: 'graph-container',
        width,
        height,
        modes: {
            default: [
                {
                    type: 'collapse-expand',
                    onChange: function onChange(item, collapsed) {
                        item.get('model').collapsed = collapsed;
                        return true;
                    },
                },
            ],
        },
        defaultNode: {
            size: 26,
            anchorPoints: [
                [0, 0.5],
                [1, 0.5],
            ],
            style: {
                fill: '#C6E5FF',
                stroke: '#5B8FF9',
            },
        },
        defaultEdge: {
            type: 'cubic-horizontal',
            style: {
                stroke: '#A3B1BF',
            },
        },
        defaultNode: {
            type: 'rect',
            style: {
                stroke: '#A3B1BF',
                width: 50,
                height: 30,
            },
        },
        layout: {
            type: 'mindmap',
            direction: 'H',
            getHeight: () => {
                return 16;
            },
            getWidth: () => {
                return 16;
            },
            getVGap: () => {
                return 10;
            },
            getHGap: () => {
                return 50;
            },
        },
    });

    // 计算中心元素坐标
    let centerX = 0;
    graph.node(function (node) {
        if (node.id === 'Modeling Methods') {
            centerX = node.x;
        }

        return {
            label: node.id,
            labelCfg: {
                position: node.children && node.children.length > 0 ? 'left' : node.x > centerX ? 'right' : 'left',
                offset: 5,
            },
        };
    });

    // 传入数据
    graph.data(data);
    // 执行渲染
    graph.render();
    // 适应当前窗口大小
    graph.fitView();

    // 绑定事件:
    // 鼠标按下时改变鼠标形状
    graph.on('node:mousedown', function(e) {
        const model = e.item.getModel();

        model.style.cursor = 'grab';
        graph.update(e.item, model);
    });
    // 恢复鼠标形状
    graph.on('node:mouseup', function(e) {
        const model = e.item.getModel();

        model.style.cursor = null;
        graph.update(e.item, model);
    });

    graph.on('node:dragstart', function(e) {
        // 提升当前节点层级(防止拖拽时被其他节点遮挡)
        e.item.toFront();

        const model = e.item.getModel();
        model.style.cursor = 'grab';
        graph.update(e.item, model);
    });
    graph.on('node:drag', function(e) {
        const { clientX, clientY, item } = e;
        const point = graph.getPointByClient(clientX, clientY);

        item.updatePosition(point);
        // 当节点位置发生变化时，刷新所有节点位置，并重计算边的位置
        graph.refreshPositions();
    });
    graph.on('node:dragend', function(e) {
        const item = e.item;
        const model = item.getModel();

        model.style.cursor = null;
        graph.update(item, model);
    });
</script>
</html>
